﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class HYPipeFittingConn : IExternalCommand
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			if (commandData == null)
			{
				throw new System.ArgumentNullException("commandData", "is null");
			}
			this.uiApp = commandData.Application;
			this.doc = this.uiApp.ActiveUIDocument.Document;
			this.sel = this.uiApp.ActiveUIDocument.Selection;
			RevitVersionFuncs.ClearSelection(this.sel);
			List<ViewType> viewTypes = YJKRevitTools.ListViewNeed(2);
			if (!YJKRevitTools.ViewCheck(this.uiApp.ActiveUIDocument, viewTypes))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			if (HYPipeFittingConn.hWndRevit == null)
			{
				HYPipeFittingConn.hWndRevit = new YJKWindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			ConnPipeFrom connPipeFrom = new ConnPipeFrom();
			connPipeFrom.Show(HYPipeFittingConn.hWndRevit);
			int wMsg = 7;
			HYPipeFittingConn.SendMessage(HYPipeFittingConn.hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			IList<Pipe> list = new List<Pipe>();
			IList<XYZ> list2 = new List<XYZ>();
			Transaction transaction = null;
			HoriPipeFilter horiPipeFilter = new HoriPipeFilter();
			HYPipeConnect hypipeConnect = new HYPipeConnect();
			ConnectPipeManage connectPipeManage = new ConnectPipeManage();
			FamilySymbol familySymbol = null;
			Element element = null;
			Result result;
			for (;;)
			{
				transaction = new Transaction(this.doc, "水管连接");
				transaction.Start();
				try
				{
					list.Clear();
					list2.Clear();
					RevitVersionFuncs.ClearSelection(this.sel);
					string text = "";
					Reference reference = this.sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, horiPipeFilter, "选择第一根水管……");
					list.Add(this.doc.GetElement(reference) as Pipe);
					list2.Add(reference.GlobalPoint);
					switch (connPipeFrom.PipeConn)
					{
					case ConnectPipeStyle.Elbow:
					{
						reference = this.sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, horiPipeFilter, "选择第二个水平水管，与第一个水管夹角大于等于90°，小于180°");
						list.Add(this.doc.GetElement(reference) as Pipe);
						list2.Add(reference.GlobalPoint);
						string text2;
						if (connPipeFrom.Flag)
						{
							familySymbol = (this.doc.GetElementById(list[0].PipeType.RoutingPreferenceManager.GetRule((Autodesk.Revit.DB.RoutingPreferenceRuleGroupType)1, 0).MEPPartId) as FamilySymbol);
							if (familySymbol == null)
							{
								YJKMessageBox.Error("没有可以使用的族配置，请检查Revit的族配置");
								break;
							}
							text2 = "";
						}
						else
						{
							text2 = connectPipeManage.GetFamilySymbolName(ConnectPipeStyle.Elbow);
						}
						if (hypipeConnect.NewElbowFitting(list, list2, text2, ref text) == null && !string.IsNullOrEmpty(text2))
						{
							YJKMessageBox.Error(text);
						}
						break;
					}
					case ConnectPipeStyle.Tee:
					{
						reference = this.sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, horiPipeFilter, "请选择第二根水管");
						list.Add(this.doc.GetElement(reference) as Pipe);
						list2.Add(reference.GlobalPoint);
						reference = this.sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, horiPipeFilter, "请选择第三根水管");
						list.Add(this.doc.GetElement(reference) as Pipe);
						list2.Add(reference.GlobalPoint);
						string text3;
						if (connPipeFrom.Flag)
						{
							int numberOfRules = list[0].PipeType.RoutingPreferenceManager.GetNumberOfRules((Autodesk.Revit.DB.RoutingPreferenceRuleGroupType)2);
							for (int i = 0; i < numberOfRules; i++)
							{
								if (list[0].PipeType.RoutingPreferenceManager.GetRule((Autodesk.Revit.DB.RoutingPreferenceRuleGroupType)2, i).MEPPartId != null)
								{
									element = this.doc.GetElementById(list[0].PipeType.RoutingPreferenceManager.GetRule((Autodesk.Revit.DB.RoutingPreferenceRuleGroupType)2, i).MEPPartId);
								}
								if (element != null)
								{
									UnifiedModified.ActivateFamilySymbol(element as FamilySymbol);
									FamilyInstance familyInstance = this.doc.Create.NewFamilyInstance(new XYZ(0.0, 0.0, 0.0), element as FamilySymbol, element, this.doc.ActiveView.GenLevel, (Autodesk.Revit.DB.Structure.StructuralType)0);
									if ((int)(familyInstance.MEPModel as MechanicalFitting).PartType == 6)
									{
										familySymbol = (element as FamilySymbol);
										this.doc.Delete(familyInstance.Id);
										break;
									}
									this.doc.Delete(familyInstance.Id);
								}
							}
							if (familySymbol == null)
							{
								YJKMessageBox.Error("没有可以使用的族配置，请检查Revit的族配置");
							}
							text3 = "";
						}
						else
						{
							text3 = connectPipeManage.GetFamilySymbolName(ConnectPipeStyle.Tee);
						}
						if (hypipeConnect.TeeFittingConnPipe(list, text3, ref text) == null && !string.IsNullOrEmpty(text3))
						{
							YJKMessageBox.Error(text);
						}
						else
						{
							this.doc.Regenerate();
						}
						break;
					}
					case ConnectPipeStyle.Cross:
					{
						reference = this.sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, horiPipeFilter, "选择第二个水管，与第一个水管在同一直线上……");
						list.Add(this.doc.GetElement(reference) as Pipe);
						list2.Add(reference.GlobalPoint);
						reference = this.sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, horiPipeFilter, "选择第三个水管，与第一、二个水管垂直……");
						list.Add(this.doc.GetElement(reference) as Pipe);
						list2.Add(reference.GlobalPoint);
						reference = this.sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, horiPipeFilter, "选择第四个水管，与第三个水管在同一直线上……");
						list.Add(this.doc.GetElement(reference) as Pipe);
						list2.Add(reference.GlobalPoint);
						string text4;
						if (connPipeFrom.Flag)
						{
							familySymbol = (this.doc.GetElementById(list[0].PipeType.RoutingPreferenceManager.GetRule((Autodesk.Revit.DB.RoutingPreferenceRuleGroupType)3, 0).MEPPartId) as FamilySymbol);
							if (familySymbol == null)
							{
								YJKMessageBox.Error("没有可以使用的族配置，请检查Revit的族配置");
								break;
							}
							text4 = "";
						}
						else
						{
							text4 = connectPipeManage.GetFamilySymbolName(ConnectPipeStyle.Cross);
						}
						if (hypipeConnect.NewCrossFitting(list, list2, text4, ref text) == null && !string.IsNullOrEmpty(text4))
						{
							YJKMessageBox.Error(text);
						}
						break;
					}
					case ConnectPipeStyle.Reduce:
					{
						reference = this.sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, horiPipeFilter, "选择第二个水管，与第一个水管在同一直线上");
						list.Add(this.doc.GetElement(reference) as Pipe);
						string text5;
						if (connPipeFrom.Flag)
						{
							familySymbol = (this.doc.GetElementById(list[0].PipeType.RoutingPreferenceManager.GetRule((Autodesk.Revit.DB.RoutingPreferenceRuleGroupType)4, 0).MEPPartId) as FamilySymbol);
							if (familySymbol == null)
							{
								YJKMessageBox.Error("没有可以使用的族配置，请检查Revit的族配置");
								break;
							}
							text5 = "";
						}
						else
						{
							text5 = connectPipeManage.GetFamilySymbolName(ConnectPipeStyle.Reduce);
						}
						if (hypipeConnect.NewTransitionFitting(list, text5, ref text) == null && !string.IsNullOrEmpty(text5))
						{
							YJKMessageBox.Error(text);
						}
						break;
					}
					case ConnectPipeStyle.Back:
					{
						reference = this.sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, horiPipeFilter, "选择第二个水平水管，与第一根水管平行……");
						list.Add(this.doc.GetElement(reference) as Pipe);
						list2.Add(reference.GlobalPoint);
						IList<FamilyInstance> list3 = new List<FamilyInstance>();
						list3 = hypipeConnect.NewBackFitting(list, ref text);
						if (list3 == null || list3.Count < 1)
						{
							YJKMessageBox.Error(text);
						}
						break;
					}
					}
					transaction.Commit();
					continue;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException)
				{
					if (transaction != null)
					{
						TransactionStatus status = transaction.GetStatus();
						if ((int)status == 1)
						{
							transaction.RollBack();
						}
						else if ((int)status == 5)
						{
							transaction.RollBack();
						}
					}
					connPipeFrom.Close();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				catch (Exception ex)
				{
					YJKMessageBox.Error(ex.Message);
					if (transaction != null)
					{
						TransactionStatus status2 = transaction.GetStatus();
						if ((int)status2 == 1)
						{
							transaction.RollBack();
						}
						else if ((int)status2 == 5)
						{
							transaction.RollBack();
						}
					}
					connPipeFrom.Close();
					result = Autodesk.Revit.UI.Result.Failed;
				}
				break;
			}
			return result;
		}

		private FamilySymbol GetFamilySymbol(string familyName, string familyFullName)
		{
			FamilySymbol familySymbol = this.GetFamilySymbol(familyName);
			if (familySymbol == null)
			{
				SubTransaction subTransaction = new SubTransaction(this.doc);
				subTransaction.Start();
				Family family = null;
				this.doc.LoadFamily(familyFullName, out family);
				if (family == null)
				{
					subTransaction.RollBack();
					return null;
				}
				familySymbol = this.GetFamilySymbol(familyName);
				subTransaction.Commit();
			}
			return familySymbol;
		}

		private FamilySymbol GetFamilySymbol(string familyName)
		{
			List<Element> elementByClass = YJKElementFilter.GetElementByClass(typeof(FamilySymbol), this.doc);
			FamilySymbol result = null;
			if (elementByClass.Count <= 0)
			{
				return null;
			}
			foreach (Element element in elementByClass)
			{
				FamilySymbol familySymbol = element as FamilySymbol;
				if (familySymbol != null && familySymbol.Family.Name == familyName)
				{
					result = familySymbol;
					break;
				}
			}
			return result;
		}

		private UIApplication uiApp;

		private Document doc;

		private Selection sel;

		public static YJKWindowHandle hWndRevit;
	}
}
